package com.base.vistter.iframe.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.vistter.iframe.entity.InverterAlarm;
import com.base.vistter.iframe.entity.InverterAlarmError;
import com.base.vistter.iframe.entity.InverterDevices;
import com.base.vistter.iframe.entity.InverterStation;
import com.base.vistter.iframe.exception.IframeException;
import com.base.vistter.iframe.mapper.InverterAlarmMapper;
import com.base.vistter.iframe.utils.ToolUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
@Slf4j
public class InverterAlarmService extends BaseService<InverterAlarmMapper, InverterAlarm> {

    @Resource(name = "inverterStationService")
    private InverterStationService inverterStationService;
    @Resource(name = "inverterDevicesService")
    private InverterDevicesService inverterDevicesService;
    @Resource(name = "inverterAlarmDetailsService")
    private InverterAlarmDetailsService inverterAlarmDetailsService;

    @Transactional(readOnly = true)
    public Page<InverterAlarm> page(Page<InverterAlarm> page, Integer status, Date beginTime, Date endTime) throws IframeException {
        LambdaQueryWrapper<InverterAlarm> lambdaQueryWrapper = this.buildLambdaQueryWrapper(status, beginTime, endTime);
        page = super.page(page, lambdaQueryWrapper);
        this.serialInverterAlarm(page.getRecords());
        return page;
    }

    @Transactional(readOnly = true)
    public Page<InverterAlarm> pageByDevicesId(Page<InverterAlarm> page, Integer devicesId) throws IframeException {
        LambdaQueryWrapper<InverterAlarm> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(InverterAlarm::getInverterDevicesId, devicesId).orderByDesc(InverterAlarm::getBeginTime);
        page = super.page(page, lambdaQueryWrapper);
        page.getRecords().forEach(item -> {
            try {
                InverterDevices inverterDevices = inverterDevicesService.getById(item.getInverterDevicesId());
                item.setChildren(inverterAlarmDetailsService.getListByAlarmId(item.getId()));
                item.setNo(inverterDevices.getNo());
                item.setCode(inverterDevices.getCode());
            }catch (IframeException e){
                log.error(e.getMessage());
            }
        });
        return page;
    }

    public void serialInverterAlarm(List<InverterAlarm> list) {
        Map<Integer, InverterStation> inverterStationMap = new HashMap<Integer, InverterStation>();
        Map<String, InverterAlarmError> inverterAlarmErrorMap = new HashMap<String, InverterAlarmError>();
        Map<Integer, InverterDevices> inverterInverterMap = new HashMap<Integer, InverterDevices>();
        list.forEach(item -> {
            try {
                InverterDevices inverterInverter = inverterInverterMap.get(item.getInverterDevicesId());
                if (inverterInverter == null) {
                    inverterInverter = inverterDevicesService.getById(item.getInverterDevicesId());
                    inverterInverterMap.put(inverterInverter.getId(), inverterInverter);
                }
                item.setNo(inverterInverter.getNo());
                item.setCode(inverterInverter.getCode());
                InverterStation inverterStation = inverterStationMap.get(inverterInverter.getInverterStationId());
                if (inverterStation == null) {
                    inverterStation = inverterStationService.getById(inverterInverter.getInverterStationId());
                    inverterStationMap.put(inverterStation.getId(), inverterStation);
                }
                item.setStationName(inverterStation.getName());
//                InverterAlarmError inverterAlarmError = inverterAlarmErrorMap.get(item.getErrorCode());
//                if (inverterAlarmError == null) {
//                    inverterAlarmError = inverterAlarmErrorService.getInverterAlarmErrorByCode(item.getErrorCode());
//                    inverterAlarmErrorMap.put(inverterAlarmError.getCode(), inverterAlarmError);
//                }
//                item.setName(inverterAlarmError.getName());
//                item.setNameEs(inverterAlarmError.getNameEs());
            } catch (IframeException e) {
                throw new RuntimeException(e);
            }
        });
    }

    @Transactional(readOnly = true)
    public List<InverterAlarm> downloadList(Integer status, Date beginTime, Date endTime) throws IframeException {
        LambdaQueryWrapper<InverterAlarm> lambdaQueryWrapper = this.buildLambdaQueryWrapper(status, beginTime, endTime);
        List<InverterAlarm> list = super.selectList(lambdaQueryWrapper);
        this.serialInverterAlarm(list);
        return list;
    }

    public LambdaQueryWrapper<InverterAlarm> buildLambdaQueryWrapper(Integer status, Date beginTime, Date endTime) {
        LambdaQueryWrapper<InverterAlarm> lambdaQueryWrapper = new LambdaQueryWrapper<InverterAlarm>();
        if (status != null) {
            lambdaQueryWrapper.eq(InverterAlarm::getStatus, status);
        }
        if (beginTime != null) {
            lambdaQueryWrapper.ge(InverterAlarm::getBeginTime, beginTime);
        }
        if (endTime != null) {
            lambdaQueryWrapper.le(InverterAlarm::getBeginTime, endTime);
        }
        return lambdaQueryWrapper;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void recover(Integer alarmId) throws IframeException{
        InverterAlarm inverterAlarm = new InverterAlarm();
        inverterAlarm.setId(alarmId);
        inverterAlarm.setEndTime(new Date());
        inverterAlarm.setStatus(2);
        super.updateById(inverterAlarm);
        inverterAlarmDetailsService.recover(alarmId);
    }

}
